/**
 * 数字人WebSocket客户端
 * 用于处理数字人相关的WebSocket连接和事件
 */
class DigitalPersonWebSocketClient {
    constructor(baseUrl, token = null) {
        this.baseUrl = baseUrl;
        this.token = token;
        this.wsUrl = `${baseUrl}/ws`;
        this.ws = null;
        this.isConnected = false;
        this.heartbeatInterval = null;
        this.heartbeatTimeout = 30000; // 30秒
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = 5;
        this.reconnectInterval = 3000; // 3秒
        this.eventHandlers = new Map();
        this.unauthorized = false; // 新增：未授权标志
    }

    /**
     * 设置token
     * @param {string} token 认证token
     */
    setToken(token) {
        this.token = token;
    }

    /**
     * 创建WebSocket连接URL
     * @returns {string} WebSocket URL
     */
    createWebSocketUrl() {
        let url = this.wsUrl;
        if (this.token) {
            const separator = url.includes('?') ? '&' : '?';
            url = `${url}${separator}token=${encodeURIComponent(this.token)}`;
        }
        return url;
    }

    /**
     * 连接WebSocket
     * @param {Function} onOpen 连接成功回调
     * @param {Function} onClose 连接关闭回调
     * @param {Function} onError 连接错误回调
     */
    connect(onOpen, onClose, onError) {
        try {
            const url = this.createWebSocketUrl();
            this.ws = new WebSocket(url);
            this.unauthorized = false; // 每次连接前重置
            
            this.ws.onopen = (event) => {
                this.isConnected = true;
                this.reconnectAttempts = 0;
                console.log('数字人WebSocket连接已建立');
                
                // 启动心跳
                this.startHeartbeat();
                
                if (onOpen) onOpen(event);
            };
            
            this.ws.onmessage = (event) => {
                console.log('收到数字人WebSocket消息:', event.data);
                this.handleMessage(event.data);
            };
            
            this.ws.onclose = (event) => {
                this.isConnected = false;
                console.log('数字人WebSocket连接已关闭');
                
                // 停止心跳
                this.stopHeartbeat();
                
                if (onClose) onClose(event);
                
                // 自动重连（未授权时不重连）
                if (!this.unauthorized && this.reconnectAttempts < this.maxReconnectAttempts) {
                    this.reconnectAttempts++;
                    console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})`);
                    setTimeout(() => this.connect(onOpen, onClose, onError), this.reconnectInterval);
                }
            };
            
            this.ws.onerror = (error) => {
                console.error('数字人WebSocket错误:', error);
                if (onError) onError(error);
            };
            
        } catch (error) {
            console.error('数字人WebSocket连接失败:', error);
            if (onError) onError(error);
        }
    }

    /**
     * 启动心跳
     */
    startHeartbeat() {
        this.stopHeartbeat(); // 先停止之前的心跳
        
        this.heartbeatInterval = setInterval(() => {
            if (this.isConnected) {
                this.sendPing();
            }
        }, this.heartbeatTimeout);
        
        console.log('数字人WebSocket心跳已启动，间隔:', this.heartbeatTimeout / 1000, '秒');
    }

    /**
     * 停止心跳
     */
    stopHeartbeat() {
        if (this.heartbeatInterval) {
            clearInterval(this.heartbeatInterval);
            this.heartbeatInterval = null;
            console.log('数字人WebSocket心跳已停止');
        }
    }

    /**
     * 发送ping消息
     */
    sendPing() {
        if (this.isConnected && this.ws) {
            const message = {
                action: 'ping',
                data: {}
            };
            try {
                this.ws.send(JSON.stringify(message));
                console.log('发送ping消息');
            } catch (error) {
                console.error('发送ping消息失败:', error);
            }
        }
    }

    /**
     * 断开连接
     */
    disconnect() {
        this.stopHeartbeat();
        if (this.ws) {
            this.ws.close();
            this.ws = null;
            this.isConnected = false;
        }
    }

    /**
     * 处理接收到的消息
     * @param {string} data 消息数据
     */
    handleMessage(data) {
        try {
            const message = JSON.parse(data);
            
            // 处理未授权事件
            if (message.event === 'unauthorized') {
                alert('Token无效或已过期，请重新输入Token并连接！');
                this.unauthorized = true; // 设置未授权标志
                // 可选：自动断开连接
                if (this.ws) {
                    this.ws.close();
                }
                return;
            }
            
            // 处理事件消息
            if (message.event) {
                this.handleEvent(message.event, message.data);
                return;
            }
            
            // 处理其他消息类型
            if (message.action) {
                console.log('收到action消息:', message.action, message.data);
                return;
            }
            
            // 处理简单文本消息
            console.log('收到文本消息:', data);
            
        } catch (error) {
            console.error('解析消息失败:', error);
            console.log('原始消息:', data);
        }
    }

    /**
     * 处理事件消息
     * @param {string} eventName 事件名称
     * @param {Object} data 事件数据
     */
    handleEvent(eventName, data) {
        console.log('处理事件:', eventName, data);
        
        // 处理定制声音相关事件
        if (eventName === 'AddCustomVoiceSuccess') {
            console.log(`你所上传的定制声音已经成功了，id=${data.id}， linkId=${data.linkId}`);
        } else if (eventName === 'AddCustomVoiceFail') {
            console.log(`你所上传的定制声音上传失败：id=${data.id}， linkId=${data.linkId}, status=${data.status}`);
        } else if (eventName === 'AddCustomDpSuccess') {
            console.log(`你所上传的定制数字人已经成功了，id=${data.id}， linkId=${data.linkId}`);
        } else if (eventName === 'AddCustomDpFail') {
            console.log(`你所上传的定制数字人上传失败：id=${data.id}， linkId=${data.linkId}, status=${data.status}`);
        } else if (eventName === 'AddDpVideoSuccess') {
            console.log(`你所上传的数字人视频已经成功了，id=${data.id}， linkId=${data.linkId}`);
        } else if (eventName === 'AddDpVideoFail') {
            console.log(`你所上传的数字人视频上传失败：id=${data.id}， linkId=${data.linkId}, status=${data.status}`);
        } else if (eventName === 'AddDpVoiceSuccess') {
            console.log(`你所上传的数字人语音合成已经成功了，id=${data.id}， linkId=${data.linkId}`);
        } else if (eventName === 'AddDpVoiceFail') {
            console.log(`你所上传的数字人语音合成失败：id=${data.id}， linkId=${data.linkId}, status=${data.status}`);
        }
        
        // 调用注册的事件处理器
        const handler = this.eventHandlers.get(eventName);
        if (handler) {
            try {
                handler(data);
            } catch (error) {
                console.error(`事件处理器错误 (${eventName}):`, error);
            }
        }
    }

    /**
     * 注册事件处理器
     * @param {string} eventName 事件名称
     * @param {Function} handler 处理函数
     */
    onEvent(eventName, handler) {
        this.eventHandlers.set(eventName, handler);
    }

    /**
     * 移除事件处理器
     * @param {string} eventName 事件名称
     */
    offEvent(eventName) {
        this.eventHandlers.delete(eventName);
    }

    /**
     * 获取连接状态
     * @returns {boolean} 是否已连接
     */
    getConnectionStatus() {
        return this.isConnected;
    }
}

// 使用示例
function createDigitalPersonWebSocket(baseUrl, token) {
    const client = new DigitalPersonWebSocketClient(baseUrl, token);
    
    // 连接WebSocket
    client.connect(
        // 连接成功回调
        (event) => {
            console.log('数字人WebSocket连接成功');
        },
        // 连接关闭回调
        (event) => {
            console.log('数字人WebSocket连接关闭');
        },
        // 连接错误回调
        (error) => {
            console.error('数字人WebSocket连接错误:', error);
        }
    );
    
    // 注册事件处理器
    client.onEvent('AddCustomVoiceSuccess', (data) => {
        console.log(`定制声音创建成功:`, data);
        // 这里可以添加UI更新逻辑
    });
    
    client.onEvent('AddCustomVoiceFail', (data) => {
        console.log(`定制声音创建失败:`, data);
        // 这里可以添加UI更新逻辑
    });
    
    return client;
}

// 导出类
if (typeof module !== 'undefined' && module.exports) {
    module.exports = { DigitalPersonWebSocketClient, createDigitalPersonWebSocket };
} 